perm filename EDITOR.S78[206,LSP] blob sn#383551 filedate 1978-09-21 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00004 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.s(EDITOR,THE LISP EDITOR)
C00004 00003	.ss(commands,  How to Use the LISP Editor.)
C00027 00004	.ss(editorex,Example session with the LISP Editor.)
C00030 ENDMK
C⊗;
.s(EDITOR,THE LISP EDITOR)

	The  LISP Editor was written by R.P.Gabriel and T.Finin.
It is a structural editor that runs in the MACLISP interpreter.
You may edit functions that are currently defined or get a
function from a file to edit.  Editing is done by manipulating
subexpressions of the defining expression for the function.
The editor knows about a top level expression and a current 
expression (CE).  Initially they are the same.  The current
expression is a list.  
You can change, add, or delete elements of the list,
move parentheses in and out to change the subexpression
structure, or change the CE by moving up, down or sideways
within the toplevel expression.  
.ss(commands,  How to Use the LISP Editor.)
     The following is taken from the online documentation of the 
LISP editor at the Stanford University AI Lab.
.begin verbatim


          The following is a very brief introduction to  the  use
     of the LISP Editor.

                       Loading the Editor
                       ------- --- ------

     1). To run the LISP Editor, one simply types  (EDIT)
         or  (EDIT  FOO)  to  edit  the in-core function "FOO" or
         (EDIT FOO FOO BAR DSK (COM RPG)) to  edit  the  function
         "FOO" in file FOO.BAR in the directory of COM,RPG.

     2). (EDIT) or (EDIT FOO) or (EDIT FOO FOO BAR) or (EDIT  FOO
         FOO  BAR  DSK (COM RPG)) can be done in LISP's that have
         an autoload property for EDIT. Typing (EDIT) causes the
	 Editor to be initialized and entered. (EDIT1 <exp>) will make
	 <exp> the toplevel editable expression. (EDIT2 <var>) will
	 make (PROG2 (SETQ <var> <current value of var>) T) the 
	 toplevel while (EDIT2 (GET <var> <indicator>)) will make it:
	 (DEFPROP <var> <value> <indicator>).

     3). (EDITV <atom>) edits the value of <atom>; the editted expression
	 is actually (prog1 (setq <atom> <value of atom>) t).

     4). (EDITP <atom> <prop>) edits the <prop> property of <atom>; the
	 actual editted expression is (defprop <atom> <value> <prop>).

              How to Look at the Current Expression (CE)
              --- -- ---- -- --- ------- ----------  --

     P        prints  the  CE  using  the  current  print   depth
              (sublist cutoff) and print length (length cutoff)
     PP       pretty-prints the entire CE
     PS       pretty-prints the CE using the print depth cutoff
     W	      prints the "window" surrounding the CE. Thus if
	      window size is 2, it prints the 2 preceeding and 2 following
	      tokens around the CE, where "token" means expression or 
	      parenthesis.

     (WINDOW n) 
	      changes the window size to n.

     (PL n)   changes the print length to n (initially 5)
     (PD n)   changes the print depth to n (initially 2)

                         Changing the CE
                         -------- --- --

     (CR E1...En) changes the  CE  to  E1...En  (i.e. splices  in
                  E1...En), and makes the CE E1.
     (n E1...En)  n>0, changes the n-th  element  of  the  CE  to
                  E1...En
     (n E1...En)  n<0 changes the n-th element of the CE from the
                  end to E1...En
     (n)          n>0 deletes the n-th element of the CE
     (n)          n<0, deletes the n-th element from the end
     RI           moves the right parenthesis in one expression
     RO           moves the right parenthesis out one expression
     LI           similar to RI
     LO           similar to RO
     DELETE       deletes the CE  (if  the  CE  is  the  toplevel
                  expression, the Editor assumes that the user
		  wants to edit a different function and requests:

          (function name <file specifications>):

     The answer can be of several forms;  examples:
        1)  FOO - loads FOO from core
        2)  (FOO FOO BAR) - loads FOO from FOO.BAR
        3)  (FOO BAR DSK (COM RPG)) - loads FOO from  FOO.BAR  in
            the directory of COM,RPG.
        4)  NEW - gives a fresh top-level expression
        5)  cntrl-G - quits back to the Editor command decoder
        6)  UNDO - <see below>.

               Moving around within the Expression
               ------ ------ ------ --- ----------

     n        n>0 makes the new CE the n-th element of the CE
     n        n<0, makes the new CE the n-th element from the end
              of the CE
     ↑        makes the CE the immediate parent of the CE
     TOP      makes the CE the toplevel expression
     NX       makes the CE the next one after the CE
     BK       makes the CE the one before the CE
     MARK     marks the current location so that it can be JUMPed
              to by the command JUMP.  Note:  MARKing and JUMPing
              is not guaranteed  to  work  in  all  cases,  since
              modification  of  the thing being edited can render
              the MARK meaningless.
     JUMP     jumps to the last MARKed location
     UNMARK   forgets  where  the  last  MARK  was  set   (speeds
              execution)

                       Adding Expressions
                       ------ -----------
     (A n E1...En) puts E1...En after the n-th element of the CE
     (B n E1...En) puts E1...En before the n-th element of the CE
     (AI E1...En)  puts E1...En after the CE and makes E1 the new CE
     (BI E1...En)  puts E1...En before the CE and  makes  E1  the new CE
     (R exp1 exp2) replaces all occurrences of exp1 with exp2  in the CE, viewed
		   as a list, returns nil? if no occurrences found
     (TR exp1 exp2)replaces all occurrences of exp1 with exp2  in the CE, viewed
		   as a tree

                       Finding Expressions (i.e. changing the CE)
                       ------- -----------  ---  -------- --- --

     (F pat)    finds the next occurrence of  pat,  searching  in
                print order
     (BF pat)   finds the next occurrence of  pat,  searching  in
                inverse print order
     (F pat T)  finds the next occurrence of pat but looks at the
                topmost  elements  of  the  CE  first (useful for
                getting to PROG tags)
     (BF pat T) similar to above
     (F pat n)  finds the n-th occurrence of pat
     (BF pat n) similar to above
     F          finds the next  occurrence  of  the  last  search
                pattern
     BF         similar to above


                             Patterns
                             --------


          Pat, as used above, can contain any of the following:
           Element of pat         What it matches
           ------- -- ---         ---- -- -------

           atom                   atoms EQ to it
           list                   calls matcher recursively
           ?                      any   atom   or   single   list
                                  (i.e. an s-expression)
           ?X                     any  element;   binds   ?X   to
                                  whatever it matched
           *                      any   non-empty    string    of
                                  elements
           *X                     matches as *, but binds  *X  to
                                  the list of elements it matched
           =?X                    whatever ?X matched last time
           =*X                    whatever *X matched last time
           (RESTRICT  ?   P1...Pn)  any  element  satisfying  the
                                  predicates P1,...,Pn
	   ($R ? P1...Pn)	  same as above.
           (RESTRICT ?X P1...Pn)  similar to above but  binds  ?X
                                  to what it matched.
	   ($R ?X P1...Pn)	  same as above.

          Note:  (A ?X IS A ?X) matches (a word is  a  word)  but
     not (a word is a sentence).  Simlarly for (*X is a *X).

                      Invoking the Matcher
                      -------- --- -------

     (MATCH pat)               attempts to match pat against the CE
     (MATCH pat var1 ... varn) attempts to match pat against the
			       CE while retaining the values of the
			       variables var1,..., varn. (E.g. 
			       (MATCH (* *A *B ?A) *A ?A).
     MATCH		       attempts to match the last pat against the
			       CE. Like F and BF above.
     REMATCH		       attempts to get the next match of pat against
			       the CE. Usually this only makes sense if
			       pat contains some * variables.
     (REMATCH var1 ... varn)   rematches but will retain var1,...,varn.


                       Hairy Matching Uses
                       ----- -------- ----

     (PR pat)         replaces the CE with the  instantiation  of
                      pat  (substitutes the values of ?-variables
                      and *-variables)
     (PA n P1...Pn)   similar to (A n E1...En)
     (PB n P1...Pn)   similar to (B n E1...En)
     (PAI P1...Pn)    similar to (AI E1...En)
     (PRA exp1 pat)   similar to (R exp1 exp2)
     (TPRA exp1 pat)  similar to (TR exp1 exp2)

                          Other Commands
                          ----- --------

     (SAVE filename <optional ext>)saves the toplevel  expression
                                   in  the file given by the file
                                   specs (will create  files  not
                                   existent), 
     [LSP is the default value for the extension.]
     SAVE			   saves the  toplevel expression
				   in the  file last saved in. If
				   there was none, the file spec.
				   is requested.
     (REFILE FOO <file specs>)     replaces the function  FOO  in
                                   the  file  given  by  the file
                                   specs with  that  found  under
                                   the "draft" property of FOO
				   where <file specs> is  of  the
				   form (file <optional ext>).
[NB: <file specs> is a 4-list (filename ext dev dir) or some
    initial segment thereof.  Thus calls to REFILE are different
    in format from those to SAVE or EDIT]
     (REFILE (FOO1...FOOn)<file specs>)
				   similar to above but refiles
                                   FOO1...FOOn.
     (REFILE (FOO1...FOOn)<infile specs><outfile specs>)
     (REFILE * <infile><optional outfile>) updates every function
				   in  infile.   Note   that  the 
				   specs are as file specs in the
				   vanilla refile above.

                                   similar to above but files the
                                   result in the outfile
     REMEMBER                      puts the  toplevel  expression
                                   under   the  "draft"  property
                                   (preserves  DEFUN  format  and
                                   comments)
     OK                            REMEMBER's  and   EVAL's   the
                                   toplevel            expression
                                   (i.e. defines the function  as
                                   well as remembers it)
     (COMMENT T)                   allows comments to be  in  the
                                   toplevel  expression (uses the
                                   grind-read-table)
     (COMMENT NIL)                 disables above
[note added by editor:  if you have comments in your files, use
";;;" rather than ";" to flag them.  Then the editor is less
likely to scramble them.]

                        The Undo Feature
                        --- ---- -------

          The Editor allows the user to "undo" any editing he has
     done.    Thus  if  he  has  made  a  mistake  or  simply  is
     experimenting, he can invoke the undo feature to  undo  each
     step.   However the undoer requires a history of the edit to
     be kept and so uses a lot of space.  Be warned!

     (UNDO T)    enables undoing
     (UNDO n)    enables  undoing  with  only  the  last undoable 
		 commands being saved (initially 6.)
     (UNDO NIL)  disables undoing and flushes the  undoqueue (the
                 history)
     UNDO        undoes the last command.  Successive UNDO's will
                 undo prior edit commands.
     The following commands can be undone:
        ↑ TOP RI RO LI LO NX BK BF DELETE F OK REMEMBER  (COMMENT
        -) (A -) (B -) (R -) (PA -) (PB -) (PAI -) (PBI -) (PL -)
        (PD -) (PRA -) (BF -) (F -) (CR -) (PR -) (AI -)  (BI  -)
        (N -) (N) N (EDPROG -).


                        Exiting and Etc.
                        ------- --- ---

     EXIT                exits the Editor (to the LISP toplevel)
     (EDIT)              gets you back to the Editor
     (REMEDIT)           flushes the Editor.
     Any other command is handed to LISP to be EVAL'ed.

.end
.next page
.ss(editorex,Example session with the LISP Editor.)

	Here are some things you can do using the Editor feature of
LISP.  The user types in lower case, LISP replys in upper case, ";;;"
flags a user comment, ";" a LISP comment.

.begin verbatim 
.select 6

;;;get the function gg from the file abc.def 
(edit gg abc def)
← ;;; the "←" means you are in the editor
;;;pretty print the definition
pp

(DEFUN GG (X) (COND ((ATOM X) X) (T (GG (CAR X)))))
 
← ;;;make gg return the right most atom instead of the left most
;;;first make (CAR X) the CE
4 3 2 2 p

← 
← 
← 
← 
(CAR X) 
;;;now change CAR to CDR
← (1 cdr)

← p

(CDR X) 
;;;remember the new definition
← remember
;;;update the definition
← (refile gg (abc def))

updated functions are: GG 
(ABC DEF DSK (4 1002)) 

;;;try out a newly defined function---fiddle
;;;note that you can evaluate expressions in the 
;;;editor as if you were at the top level of LISP
← (fiddle 'x)

(X . X) 

← (fiddle '(x.y))
SPEC PDL OVERFLOW
;;;oops must be a bug
← (edit fiddle)

(FIDDLE) 
← pp


(DEFUN FIDDLE (X) 
       (COND ((ATOM X) (DOUBLE X))
             (T (FIDDLE (CONS (CDR X) (CAR X))))))

;;;hmmm better fix it
← 4 3 2 (1 cons) pp

← 
← 
← 
← 

(CONS (CONS (CDR X) (CAR X)))
 
← (2 (fiddle (cdr x)) (fiddle (car x)))

← p

(CONS (FIDDLE #) (FIDDLE #)) 
;;;remember the new definition and 
;;;redefine the function
← ok

FIDDLE 
← (fiddle 'x)

(X . X) 
← (fiddle '(x.y))

((Y . Y) X . X) 
;;; save it fiddle.lsp
← (save fiddle)

(DSK (4 1002)) 
;;; copy functions in abc.def into uvw.xyz updating any that the editor
;;;knows have been changed.  
← (refile * (abc def) (uvw xyz))

updated functions are: GG GG DOUBLE DOUBLE 
(UVW XYZ DSK (4 1002)) 
;;;abc.def is unchanged
.end